import 'package:flutter/foundation.dart';
import '../../data/api/directories_api.dart';
import '../../data/models/api_response.dart';
import '../../data/models/directory.dart';
import '../../core/exceptions/app_exception.dart';

/// 目录服务，封装目录API的调用
class DirectoryService extends ChangeNotifier {
  final DirectoriesApi _directoriesApi;

  // 当前目录ID
  int _currentDirectoryId = 0;

  // 当前目录路径历史
  List<Directory> _directoryPathHistory = [];

  // 当前目录的子目录
  List<Directory> _subdirectories = [];

  // 当前目录的文件
  List<FileItem> _files = [];

  // 目录树
  List<Directory> _directoryTree = [];

  // 加载状态
  bool _isLoading = false;

  // 错误消息
  String? _errorMessage;

  // Getters
  int get currentDirectoryId => _currentDirectoryId;
  List<Directory> get directoryPathHistory =>
      List.unmodifiable(_directoryPathHistory);
  List<Directory> get subdirectories => List.unmodifiable(_subdirectories);
  List<FileItem> get files => List.unmodifiable(_files);
  List<Directory> get directoryTree => List.unmodifiable(_directoryTree);
  bool get isLoading => _isLoading;
  String? get errorMessage => _errorMessage;

  DirectoryService({DirectoriesApi? directoriesApi})
    : _directoriesApi = directoriesApi ?? DirectoriesApi();

  /// 安全地通知监听器（在微任务中执行以避免在构建过程中触发通知）
  void _safeNotifyListeners() {
    Future.microtask(() {
      notifyListeners();
    });
  }

  /// 设置认证Token
  void setAuthToken(String token) {
    _directoriesApi.setAuthToken(token);
    // 不需要通知监听器，因为这只是修改内部API配置
  }

  /// 重置目录服务状态
  void reset() {
    _currentDirectoryId = 0;
    _directoryPathHistory = [];
    _subdirectories = [];
    _files = [];
    _directoryTree = [];
    _errorMessage = null;
    _safeNotifyListeners();
  }

  /// 加载根目录
  Future<void> loadRootDirectory() async {
    await navigateToDirectory(0);
  }

  /// 导航到指定目录
  Future<void> navigateToDirectory(int directoryId) async {
    _setLoading(true);
    _clearError();

    try {
      // 如果是返回到历史目录
      if (_directoryPathHistory.any((dir) => dir.id == directoryId)) {
        // 找到历史路径中的位置
        final index = _directoryPathHistory.indexWhere(
          (dir) => dir.id == directoryId,
        );
        // 截断历史路径
        _directoryPathHistory = _directoryPathHistory.sublist(0, index + 1);
      } else {
        // 如果是导航到新目录
        final response = await _directoriesApi.getDirectory(directoryId);

        if (!response.isSuccess || response.data == null) {
          throw ApiException(response.message, code: response.code);
        }

        // 添加到历史路径
        _directoryPathHistory.add(response.data!);
      }

      // 更新当前目录ID
      _currentDirectoryId = directoryId;

      // 加载当前目录的子目录和文件
      await Future.wait([_loadSubdirectories(), _loadFiles()]);
    } catch (e) {
      _setError(e is AppException ? e.message : '加载目录失败: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 加载子目录
  Future<void> _loadSubdirectories() async {
    try {
      final response = await _directoriesApi.getDirectories(
        parentId: _currentDirectoryId,
      );

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      _subdirectories = response.data ?? [];
    } catch (e) {
      debugPrint('加载子目录失败: $e');
      _subdirectories = [];
      rethrow;
    }
  }

  /// 加载文件
  Future<void> _loadFiles() async {
    try {
      final response = await _directoriesApi.getDirectoryFiles(
        _currentDirectoryId,
      );

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      _files = response.data ?? [];
    } catch (e) {
      debugPrint('加载文件失败: $e');
      _files = [];
      rethrow;
    }
  }

  /// 创建目录
  Future<void> createDirectory(String name) async {
    _setLoading(true);
    _clearError();

    try {
      final response = await _directoriesApi.createDirectory(
        name: name,
        parentId: _currentDirectoryId,
      );

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      // 刷新子目录列表
      await _loadSubdirectories();
    } catch (e) {
      _setError(e is AppException ? e.message : '创建目录失败: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 重命名目录
  Future<void> renameDirectory(int directoryId, String newName) async {
    _setLoading(true);
    _clearError();

    try {
      final response = await _directoriesApi.updateDirectory(
        directoryId: directoryId,
        name: newName,
      );

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      // 如果是当前路径中的某个目录，更新路径历史
      final pathIndex = _directoryPathHistory.indexWhere(
        (dir) => dir.id == directoryId,
      );
      if (pathIndex >= 0) {
        final updatedDir = _directoryPathHistory[pathIndex].copyWith(
          name: newName,
        );
        _directoryPathHistory[pathIndex] = updatedDir;
      }

      // 刷新子目录列表
      await _loadSubdirectories();
    } catch (e) {
      _setError(e is AppException ? e.message : '重命名目录失败: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 删除目录
  Future<void> deleteDirectory(
    int directoryId, {
    bool permanent = false,
  }) async {
    _setLoading(true);
    _clearError();

    try {
      final response = await _directoriesApi.batchDeleteItems(
        directoryIds: [directoryId],
        permanent: permanent,
        recursive: true,
      );

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      // 刷新子目录列表
      await _loadSubdirectories();
    } catch (e) {
      _setError(e is AppException ? e.message : '删除目录失败: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 移动目录
  Future<void> moveDirectory(int directoryId, int targetDirectoryId) async {
    _setLoading(true);
    _clearError();

    try {
      final response = await _directoriesApi.moveItems(
        directoryIds: [directoryId],
        targetDirectoryId: targetDirectoryId,
      );

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      // 刷新子目录列表
      await _loadSubdirectories();
    } catch (e) {
      _setError(e is AppException ? e.message : '移动目录失败: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 删除文件
  Future<void> deleteFile(int fileId, {bool permanent = false}) async {
    _setLoading(true);
    _clearError();

    try {
      final response = await _directoriesApi.batchDeleteItems(
        fileIds: [fileId],
        permanent: permanent,
      );

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      // 刷新文件列表
      await _loadFiles();
    } catch (e) {
      _setError(e is AppException ? e.message : '删除文件失败: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 移动文件
  Future<void> moveFile(int fileId, int targetDirectoryId) async {
    _setLoading(true);
    _clearError();

    try {
      final response = await _directoriesApi.moveItems(
        fileIds: [fileId],
        targetDirectoryId: targetDirectoryId,
      );

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      // 刷新文件列表
      await _loadFiles();
    } catch (e) {
      _setError(e is AppException ? e.message : '移动文件失败: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 加载目录树
  Future<void> loadDirectoryTree() async {
    _setLoading(true);
    _clearError();

    try {
      final response = await _directoriesApi.getDirectoryTree();

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      _directoryTree = response.data ?? [];
    } catch (e) {
      _setError(e is AppException ? e.message : '加载目录树失败: ${e.toString()}');
      _directoryTree = [];
    } finally {
      _setLoading(false);
    }
  }

  /// 返回上级目录
  Future<void> navigateToParentDirectory() async {
    if (_directoryPathHistory.length <= 1) {
      // 已经在根目录，无法再向上
      return;
    }

    // 移除当前目录
    _directoryPathHistory.removeLast();

    // 获取上一级目录ID
    final parentDirectory = _directoryPathHistory.last;
    _currentDirectoryId = parentDirectory.id;

    // 加载当前目录的子目录和文件
    _setLoading(true);
    _clearError();

    try {
      await Future.wait([_loadSubdirectories(), _loadFiles()]);
    } catch (e) {
      _setError(e is AppException ? e.message : '加载上级目录失败: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 批量删除目录和文件
  Future<void> batchDeleteItems({
    List<int>? directoryIds,
    List<int>? fileIds,
    bool permanent = false,
  }) async {
    if ((directoryIds == null || directoryIds.isEmpty) &&
        (fileIds == null || fileIds.isEmpty)) {
      return;
    }

    _setLoading(true);
    _clearError();

    try {
      final response = await _directoriesApi.batchDeleteItems(
        directoryIds: directoryIds,
        fileIds: fileIds,
        permanent: permanent,
        recursive: true,
      );

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      // 刷新列表
      await Future.wait([_loadSubdirectories(), _loadFiles()]);
    } catch (e) {
      _setError(e is AppException ? e.message : '批量删除失败: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 批量移动目录和文件
  Future<void> batchMoveItems({
    List<int>? directoryIds,
    List<int>? fileIds,
    required int targetDirectoryId,
  }) async {
    if ((directoryIds == null || directoryIds.isEmpty) &&
        (fileIds == null || fileIds.isEmpty)) {
      return;
    }

    _setLoading(true);
    _clearError();

    try {
      final response = await _directoriesApi.moveItems(
        directoryIds: directoryIds,
        fileIds: fileIds,
        targetDirectoryId: targetDirectoryId,
      );

      if (!response.isSuccess) {
        throw ApiException(response.message, code: response.code);
      }

      // 刷新列表
      await Future.wait([_loadSubdirectories(), _loadFiles()]);
    } catch (e) {
      _setError(e is AppException ? e.message : '批量移动失败: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 查找目录树中的特定目录
  Directory? findDirectoryInTree(int directoryId) {
    return _findDirectoryInList(_directoryTree, directoryId);
  }

  Directory? _findDirectoryInList(
    List<Directory> directories,
    int directoryId,
  ) {
    for (final directory in directories) {
      if (directory.id == directoryId) {
        return directory;
      }

      if (directory.children != null && directory.children!.isNotEmpty) {
        final found = _findDirectoryInList(directory.children!, directoryId);
        if (found != null) {
          return found;
        }
      }
    }

    return null;
  }

  /// 设置加载状态
  void _setLoading(bool value) {
    _isLoading = value;
    _safeNotifyListeners();
  }

  /// 设置错误信息
  void _setError(String message) {
    _errorMessage = message;
    _safeNotifyListeners();
  }

  /// 清除错误信息
  void _clearError() {
    _errorMessage = null;
  }

  /// 释放资源
  @override
  void dispose() {
    _directoriesApi.dispose();
    super.dispose();
  }
}
